mongodb aggregation pipeline

Q. How to lookup and filter in a pipeline?

To perform a lookup and filter in a MongoDB aggregation pipeline, follow these steps:

1. Use $lookup for Joining Collections

The $lookup stage allows you to join another collection based on a foreign key.

{
  "$lookup": {
    "from": "academymodels",        // The collection to join
    "localField": "academy",        // The field in the current collection
    "foreignField": "_id",          // The field in the "from" collection
    "as": "academyDetails"          // The alias for the joined documents
  }
}

2. Use $match to Filter the Results

Once you've performed the $lookup, you can filter the documents based on conditions.

{
  "$match": {
    "businessDays": { "$size": 0 }  // Filtering condition
  }
}

3. Combine $lookup and $match in a Pipeline

A complete pipeline combining $lookup and $match would look like this:

[
  {
    "$lookup": {
      "from": "academymodels",
      "localField": "academy",
      "foreignField": "_id",
      "as": "academyDetails"
    }
  },
  {
    "$match": {
      "businessDays": { "$size": 0 }  // Filters documents where businessDays is empty
    }
  }
]

Explanation

  1. $lookup joins academymodels with courtmodes using the academy field.

  2. $match filters out documents where businessDays is empty.

Next Steps

Q. Why lookup result is array? It is only one to one relationship.

The $lookup stage in MongoDB always returns an array because MongoDB is designed to support one-to-many relationships by default. Even in a one-to-one relationship, $lookup treats it as a potential one-to-many and returns an array of matched documents.

Why Does $lookup Return an Array?


How to Convert the $lookup Array into a Single Object?

If you expect only one matching document, you can use $unwind to transform the array into an object.

Modify the Pipeline

[
  {
    "$lookup": {
      "from": "academymodels",
      "localField": "academy",
      "foreignField": "_id",
      "as": "academyDetails"
    }
  },
  {
    "$unwind": {
	  "path": '$ticketPlanDetails',
	  "preserveNullAndEmptyArrays": true
	}  // Converts the array to a single object
  }
]

How $unwind Works


Alternative: Using $arrayElemAt

If you don't want to unwind but still need the first element as an object:

[
  {
    "$lookup": {
      "from": "academymodels",
      "localField": "academy",
      "foreignField": "_id",
      "as": "academyDetails"
    }
  },
  {
    "$set": {
      "academyDetails": { "$arrayElemAt": ["$academyDetails", 0] }
    }
  }
]

Why $arrayElemAt?


Which One Should You Use?

Method Use Case
$unwind If you want to normalize the structure and treat it as a true one-to-one relationship.
$arrayElemAt If you want to keep the document intact but still extract only one object.

Let me know if you need further refinements! 🚀